package com.h5lib.xlsx4j;

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;

import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;

/**
 * 
 * @author xlsx 写入
 *
 */
public class XLSXWriter implements Closeable {

    private XLSXResource xlsxResource;
    private ZipFile xlsx;
    private File xlsFile;
    private File zipFile;
    private XMLSharedStringWriter sharedStringWriter=null;
    
    public XLSXWriter(String name) throws WriterException {
    	zipFile = new File(name+System.currentTimeMillis()+".zip");
    	xlsFile = new File(name);
    	if(xlsFile.exists()){
    		throw new WriterException("文件已经存在");
    	}
    	xlsxResource = new StreamXLSXResource(getClass().getResourceAsStream("/template.zip"));
    }
    
    public XLSXWriter(String name,InputStream template) {
    	xlsxResource = new StreamXLSXResource(template);
    }

    /**
     * 
     * @param i
     * @return
     * @throws IOException
     * @throws XmlPullParserException
     */
    public XMLSheetWriter createSheet(int i) throws IOException, XmlPullParserException {
        String name = "xl/worksheets/sheet" + (i + 1) + ".xml";
        if( !xlsxResource.has(name) ) {
            throw new FileNotFoundException(name);
        }
        XMLSheetWriter writer = XMLSheetWriter(name);
        return writer;
    }

    private XMLSheetWriter XMLSheetWriter(String name) throws IOException, XmlPullParserException {
        OutputStream out = xlsxResource.out(name);
        XmlSerializer newSerializer = XmlPullParserFactory.newInstance().newSerializer();
        newSerializer.setOutput(out, "UTF-8");
        XMLSheetWriter writer = new XMLSheetWriter(newSerializer);
        if(sharedStringWriter == null){
        	sharedStringWriter = getSharedStringWriter();
        }
        writer.setSharedStringWriter(sharedStringWriter);
        return writer;
    }
    
    public XMLSharedStringWriter getSharedStringWriter() throws IOException, XmlPullParserException {

        OutputStream out = xlsxResource.out("xl/sharedStrings.xml");
        XmlSerializer newSerializer = XmlPullParserFactory.newInstance().newSerializer();
        newSerializer.setOutput(out, "UTF-8");
        XMLSharedStringWriter reader = new XMLSharedStringWriter(newSerializer);

        return reader;
    }

    
    @Override
    public void close() throws IOException {
    	sharedStringWriter.close();
		try {
			xlsx = new ZipFile(zipFile);
    		ZipParameters parameters = new ZipParameters();  
    		parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);  
    		parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
    		parameters.setSourceExternalStream(true);
	    	Map<String, File> files = xlsxResource.files();
	    	for(Map.Entry<String, File> entry :files.entrySet()){
	    		parameters.setFileNameInZip(entry.getKey());
	    		File value = entry.getValue();
				xlsx.addStream(new FileInputStream(value), parameters);
	    	}
		} catch (ZipException e) {
			e.printStackTrace();
		}
		zipFile.renameTo(xlsFile);
        xlsxResource.close();

    }
}
